<template>
  <div class="role-manage-wrapper">
    <el-form :inline="true" :model="formInline">
      <el-form-item label="角色名称">
        <el-input v-model="formInline.roleNameLike" placeholder="请输入角色名称" clearable></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="searchSource">查询</el-button>
        <el-button type="primary" @click="popNewAddDialog">新增角色</el-button>
      </el-form-item>
    </el-form>
    <el-table :data="tableData" ref="multipleTable" v-loading="loading" stripe>
      <el-table-column label="序号" width="50">
        <template slot-scope="scope">{{ scope.$index + startNum + 1 }}</template>
      </el-table-column>
      <el-table-column label="角色名称" prop="roleName"></el-table-column>
      <el-table-column label="角色描述" prop="remark"></el-table-column>
      <el-table-column label="创建时间" prop="addTime"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-link type="primary" :underline="false" icon="el-icon-edit" @click="editDetail(scope.row.roleId)">编辑</el-link>&nbsp;
          <el-link type="warning" :underline="false" icon="el-icon-coin" @click="assignPermit(scope.row.roleId)">分配权限</el-link>&nbsp;
          <el-link type="danger" :underline="false" icon="el-icon-delete" @click="deleteDetail(scope.row.roleId)">删除</el-link>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      class="paging-self"
      background
      :current-page.sync="currentPage"
      @current-change="pageChange"
      layout="total, prev, pager, next"
      :total="totalCount">
    </el-pagination>
    <!-- 对话框 开始 -->
    <el-dialog :title="permitting?'分配权限':'角色管理'" :visible.sync="dialogFormVisible" width="660px" @closed="closeDialog" :close-on-click-modal="false">
      <el-form :model="dialogForm" class="dialog-form-comot" :disabled="dialogMode===CNST.READ_MODE" :rules="rules" ref="ruleDialog" v-if="!permitting">
        <el-form-item label="角色名称" label-width="100px" prop="roleName">
          <el-input v-model="dialogForm.roleName" placeholder="请输入角色名称" autocomplete="off" maxlength="20"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" label-width="100px" prop="remark">
          <el-input type="textarea" v-model="dialogForm.remark" placeholder="请输入角色描述" autocomplete="off" maxlength="1800"></el-input>
        </el-form-item>
      </el-form>
      <el-tree
        ref="treeComt"
        v-if="permitting"
        :data="treeData"
        show-checkbox
        :check-strictly="true"
        node-key="resourceId"
        :default-expanded-keys="[]"
        :default-checked-keys="[]"
        :props="defaultProps"
        @check="handleCheck">
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitOrg" v-if="dialogMode!==CNST.READ_MODE">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 对话框 结束 -->
  </div>
</template>

<script>
import {
  getRoleList,
  getRoleResourceList,
  addRole,
  getRoleDetail,
  updateRole,
  deleteRole,
  addRoleResource
} from '@/api/systemManage'
import { deepClone } from '@/utils'
export default {
  name: 'RoleManage',
  data () {
    return {
      formInline: {
        roleNameLike: ''
      },
      tableData: [],
      loading: false,
      dialogMode: '',
      dialogFormVisible: false,
      dialogForm: {
        roleName: '',
        remark: ''
      },
      rules: {
        roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
        remark: [{ required: true, message: '请输入角色描述', trigger: 'blur' }]
      },
      curId: '',
      totalCount: 0, // 总共多少条
      currentPage: 1, // 分页当前页
      permitting: false,
      listData: [],
      treeData: [],
      checkedResourceIdArr: [],
      defaultProps: {
        children: 'children',
        label: 'resourceName'
      },
      startNum: 0
    }
  },
  computed: {
  },
  methods: {
    async getListAndShow () {
      try {
        this.loading = true
        let requestData = {
          page: this.currentPage,
          pageSize: 10,
          roleNameLike: this.formInline.roleNameLike.trim()
        }
        var res = await getRoleList(requestData)
        this.tableData = res.data.queryResult
        this.totalCount = res.data.totalCount
      } catch (error) {
        console.error(error)
      } finally {
        this.loading = false
      }
    },
    searchSource () {
      this.currentPage = 1
      this.getListAndShow()
    },
    pageChange (curPage) {
      this.currentPage = curPage
      this.getListAndShow()
    },
    popNewAddDialog () {
      this.dialogFormVisible = true
      this.dialogMode = this.CNST.ADDNEW_MODE
    },
    handleChange (value) {
      console.log(value)
    },
    idRelationParent (target = {}, idsArr = []) {
      if (target.parentId !== '0') {
        let parent = this.listData.filter(item => item.resourceId === target.parentId)
        idsArr.push(parent[0].resourceId)
        this.idRelationParent(parent[0], idsArr)
      }
    },
    idRelationChild (target = {}, idsArr = []) {
      idsArr.push(target.resourceId)
      if (target.children) {
        target.children.forEach((item) => {
          this.idRelationChild(item, idsArr)
        })
      }
    },
    handleCheck (activeNode, checkedInfo) {
      if (this.checkedResourceIdArr.includes(activeNode.resourceId)) {
        let childIdArr = []
        this.idRelationChild(activeNode, childIdArr)
        for (let i = 0; i < this.checkedResourceIdArr.length; i++) {
          if (childIdArr.includes(this.checkedResourceIdArr[i])) {
            this.checkedResourceIdArr.splice(i, 1)
            i--
          }
        }
        this.$refs.treeComt.setCheckedKeys(this.checkedResourceIdArr)
      } else {
        this.idRelationChild(activeNode, this.checkedResourceIdArr)
        this.idRelationParent(activeNode, this.checkedResourceIdArr)
        this.$refs.treeComt.setCheckedKeys(this.checkedResourceIdArr)
      }
    },
    assignPermit (roleId) {
      this.permitting = true
      this.dialogMode = this.CNST.EDIT_MODE
      this.dialogFormVisible = true
      this.curId = roleId
      getRoleResourceList({ roleId }).then((res) => {
        this.listData = res.data.queryResult
        this.treeData = this.toTreeResource(JSON.parse(JSON.stringify(res.data.queryResult)))
        let checkedArr = res.data.queryResult.filter(item => item.authority)
        let idArr = checkedArr.map(item => item.resourceId)
        this.$nextTick(() => {
          this.checkedResourceIdArr = idArr
          this.$refs.treeComt.setCheckedKeys(idArr)
        })
      })
    },
    editDetail (roleId) {
      this.dialogMode = this.CNST.EDIT_MODE
      this.dialogFormVisible = true
      this.curId = roleId
      getRoleDetail({ roleId }).then((res) => {
        this.showToDialog(res.data)
      })
    },
    deleteDetail (roleId) {
      this.$confirm('确定删除, 是否继续?', '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then((res) => {
        deleteRole({ roleId }).then((res) => {
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
          this.getListAndShow()
        })
      })
    },
    showToDialog (data) {
      for (let key in data) {
        if (this.dialogForm.hasOwnProperty(key)) {
          this.dialogForm[key] = data[key]
        }
      }
    },
    closeDialog () {
      this.dialogMode = ''
      // 当前点击查看或编辑列表项的id置空
      this.curId = ''
      // 弹框关闭后重置表单验证
      if (!this.permitting) {
        this.$refs.ruleDialog.resetFields()
      }
      // 清空弹框内表单数据
      for (let key in this.dialogForm) {
        this.dialogForm[key] = ''
      }
      this.permitting = false
    },
    submitOrg () {
      if (this.permitting) {
        let obj = {
          roleId: this.curId,
          resourceId: this.checkedResourceIdArr.join(',')
        }
        if (!obj.resourceId) {
          this.$message({
            message: '请勾选分配权限',
            type: 'warning'
          })
          return
        }
        addRoleResource(obj).then(() => {
          this.$message({
            message: '分配权限成功',
            type: 'success'
          })
          this.dialogFormVisible = false
        })
        return
      }
      this.$refs.ruleDialog.validate((valid) => {
        if (valid) {
          let requestData = deepClone(this.dialogForm)
          if (this.dialogMode === this.CNST.ADDNEW_MODE) {
            // 新增
            addRole(requestData).then((res) => {
              this.$message({
                message: '新增成功',
                type: 'success'
              })
              this.getListAndShow()
              this.dialogFormVisible = false
            })
          } else if (this.dialogMode === this.CNST.EDIT_MODE) {
            // 修改
            requestData.roleId = this.curId
            updateRole(requestData).then((res) => {
              this.$message({
                message: '修改成功',
                type: 'success'
              })
              this.getListAndShow()
              this.dialogFormVisible = false
            })
          }
        } else {
          return false
        }
      })
    },
    toTreeResource (data) {
      // 删除 所有 children,以防止多次调用
      data.forEach(function (item) {
        item.title = item.resourceName
        item.key = item.resourceId
        delete item.isLeaf
        delete item.children
      })
      // 将数据存储为 以 id 为 KEY 的 map 索引数据列
      var map = {}
      data.forEach(function (item) {
        map[item.resourceId] = item
      })

      var val = []
      data.forEach(function (item) {
        // 以当前遍历项的pid,去map对象中找到索引的id
        var parent = map[item.parentId]
        // 如果找到索引，那么说明此项不在顶级当中,那么需要把此项新增到，他对应的父级中
        if (parent) {
          (parent.children || (parent.children = [])).push(item)
        } else {
          // 如果没有在map中找到对应的索引ID,那么直接把 当前的item新增到 val结果集中，作为顶级
          val.push(item)
        }
      })
      return val
    }
  },
  mounted () {
    this.getListAndShow()
  }
}
</script>

<style lang="scss" scoped>
.role-manage-wrapper {
  height: calc(100vh - 180px);
  background-color: #ffffff;
  padding: 15px;
  box-shadow: 10px 10px 22px -2px #d2d6da;
  border-radius: 3px;
  .el-form.dialog-form-comot {
    .el-form-item {
      .el-cascader,.el-select {
        width: 100%;
      }
    }
  }
  .el-pagination.paging-self {
    margin-top: 20px;
    float: right;
  }
  .el-tree {
    /deep/.el-tree-node__content>.el-checkbox {
      margin-right: 8px;
    }
  }
}
</style>
